package main

import (
	"fmt"
	"runtime"
	"sync"
)

type Task interface {
	Execute()
	GetResult() string
}

type DoctorTask struct {
	Wg     *sync.WaitGroup
	Result string
}

func (task *DoctorTask) Execute() {
	task.Result = "医生的工作：诊疗"
	task.Wg.Done()
}

func (task *DoctorTask) GetResult() string {
	return task.Result
}

type WorkerTask struct {
	Wg     *sync.WaitGroup
	Result string
}

func (task *WorkerTask) Execute() {
	task.Result = "工人的工作：生产"
	task.Wg.Done()
}

func (task *WorkerTask) GetResult() string {
	return task.Result
}

type TeacherTask struct {
	Wg     *sync.WaitGroup
	Result string
}

func (task *TeacherTask) Execute() {
	task.Result = "教师的工作：教学"
	task.Wg.Done()
}

func (task *TeacherTask) GetResult() string {
	return task.Result
}

type RoutinePool struct {
	coreNum  int
	TaskList chan Task
}

func NewPool(core int) *RoutinePool {
	// 如果核心协程数目为0，则将其置为CPU核心数
	if core == 0 {
		core = runtime.NumCPU()
	}

	// 创建RoutinePool实例
	p := &RoutinePool{
		TaskList: make(chan Task),
	}

	// 按核心协程数目，启动子协程
	for i := 0; i < core; i++ {
		go func() {
			// 子协程内部，不断从任务列表中获取任务对象Task，并执行任务
			for task := range p.TaskList {
				task.Execute()
			}
		}()
	}
	return p
}

// 向协程池提交新的任务
func (p *RoutinePool) Submit(t Task) {
	p.TaskList <- t
}

func main12() {
	// 创建核心协程数为2的协程池
	pool := NewPool(2)
	// 创建等待组
	var wg sync.WaitGroup

	// 创建医生任务
	doctorTask := &DoctorTask{
		Wg: &wg,
	}
	// 等待组计数器加1
	wg.Add(1)
	// 提交医生任务
	pool.Submit(doctorTask)

	// 创建工人任务
	workerTask := &WorkerTask{
		Wg: &wg,
	}
	wg.Add(1)
	// 提交工人任务
	pool.Submit(workerTask)

	// 创建教师任务
	teacherTask := &TeacherTask{
		Wg: &wg,
	}
	wg.Add(1)
	// 提交教师任务
	pool.Submit(teacherTask)

	// 等待组阻塞
	wg.Wait()

	// 打印各任务执行结果
	fmt.Println(doctorTask.GetResult())
	fmt.Println(workerTask.GetResult())
	fmt.Println(teacherTask.GetResult())
}
